import type { FieldProps } from 'sula';
import type { ItemLayout } from 'sula/es/form/FieldGroup';
import type { ValueTextType, KeyObj } from '@/constants';
import type { PluginCtx } from 'sula/es/types/ctx';
import type { RenderCtx } from 'sula/es/types/plugin';
import { Tooltip, Tag, Button } from 'antd';
import { getBrandListConfig } from '@/pages/content-manage/brand/service';
import { searchContract, searchCompany } from '@/services/global/base';
import { getContractSearchConfig } from '@/sula-plugin/service';
import moment from 'moment';
import type { Moment } from 'moment';
import { ExclamationCircleOutlined } from '@ant-design/icons';
import { numberRange, listToOptions } from '@/utils/utils';
import isBoolean from 'lodash/isBoolean';
import styles from './style.less';

export const singleColLayout = {
  span: 24,
  labelCol: { span: 24 },
  wrapperCol: { span: 24 },
};

export const twoColLayout = {
  span: 12,
  labelCol: { span: 24 },
  wrapperCol: { span: 24 },
};

export const threeColLayout = {
  span: 8,
  labelCol: { span: 24 },
  wrapperCol: { span: 24 },
};

export const fourColLayout = {
  span: 6,
  labelCol: { span: 24 },
  wrapperCol: { span: 24 },
};
export const fiveColLayout = {
  span: 5,
  labelCol: { span: 24 },
  wrapperCol: { span: 24 },
};
export const sixColLayout = {
  span: 4,
  labelCol: { span: 24 },
  wrapperCol: { span: 24 },
};

export const fieldsItemDivConstructor = (
  itemLayout: ItemLayout,
  fields: any[],
  restProps?: any,
  containerProps?: any,
) => {
  return {
    container: {
      type: 'div',
      ...containerProps,
    },
    itemLayout,
    fields,
    ...restProps,
  };
};

type remarkProps = {
  name: string | string[];
  dependency?: any;
};

type FieldPropsWithDeal = FieldProps & {
  rValueInit?: (value: any) => any;
  rValueSubmit?: (value: any) => any;
};
export const remarksItemConstructor = (
  sourceItem: FieldPropsWithDeal,
  remarkProps: remarkProps = { name: '', dependency: {} },
) => {
  const item = { ...sourceItem };
  delete item.label;
  const name = remarkProps.name || `${sourceItem.name}Remarks`;
  const { dependency } = remarkProps;
  return {
    name: `${sourceItem.name}Items`,
    label: sourceItem.rules ? (
      <span className={styles['ant-form-item-inner-required']}>{sourceItem.label}</span>
    ) : (
      sourceItem.label
    ),
    field: {
      type: 'fieldsCollapse',
      props: {
        require: true,
        fields: [
          item,
          {
            name,
            field: {
              type: 'enhancedInput',
              props: {
                placeholder: `${sourceItem.label}备注:`,
              },
            },
            initialVisible: false,
            dependency,
          },
        ],
      },
    },
  };
};

export type GetBrandListRemoteSelectConfigParamsType = {
  mode?: string;
  companyIdList?: (string | number)[];
  name: string;
  label: string;
  [key: string]: any;
};

export const getBrandListRemoteSelectConfig = ({
  mode,
  name,
  label,
  ...restProps
}: GetBrandListRemoteSelectConfigParamsType) => {
  return {
    name,
    label,
    field: {
      type: 'remoteSelect',
      props: {
        placeholder: '输入公司ID或者公司名搜索',
        fetchOptions: searchCompany,
        formatOptions: (res: any) => {
          const { code, data } = res;
          if (code === '0') {
            return listToOptions(data.list, 'companyId', 'companyName');
          }
          return [];
        },
        formatPropsValue: (val: any) => {
          if (val === 0) {
            return null;
          }
          return val;
        },
        filterOption: (options: ValueTextType[], ctx: PluginCtx) => {
          if (!ctx) {
            return options;
          }
          const { record } = ctx;
          if (!record?.companyId || !Array.isArray(options) || options.length === 0) {
            return options;
          }
          const compList = options.filter((option) => {
            return option.value !== record.companyId;
          });
          return compList;
        },
      },
    },
    remoteSource:
      mode !== 'create' &&
      getBrandListConfig({
        params: {
          filters: {
            searchType: 'companyIdList',
            companyIdList: [`#{record.${name}}`],
          },
        },
        convertParams: true,
        converter: true,
      }),
    ...restProps,
  };
};

export type GetContractListRemoteSelectConfigParamsType = {
  mode?: string;
  companyIdList?: (string | number)[];
  name: string;
  label: string;
  copyrightCompanyName?: string;
  dependency?: boolean | Record<string, any>;
  restFieldProps?: Record<string, any>;
};

// 合同搜索sula配置，可关联表单中版权公司字段，进行禁用和值清除操作，自定义form需搭配ctxGetter进行表格向表单的上下文(record属性)传递
export const getContractListRemoteSelectConfig = ({
  mode,
  name,
  label,
  copyrightCompanyName,
  dependency = true,
  restFieldProps,
}: GetContractListRemoteSelectConfigParamsType) => {
  const dependencyConfig = () => {
    if (isBoolean(dependency)) {
      if (dependency) {
        return {
          disabled: {
            relates: [copyrightCompanyName],
            type: (ctx: any) => {
              if (ctx.values[0]) {
                ctx.form.setFieldDisabled(ctx.name[0], false);
              } else {
                ctx.form.setFieldDisabled(ctx.name[0], true);
              }
            },
          },
          value: {
            relates: [copyrightCompanyName],
            type: (ctx: any) => {
              if (!ctx.values[0]) {
                ctx.form.setFieldValue(ctx.name[0], null);
              }
            },
          },
        };
      }
    } else {
      return dependency;
    }
    return {};
  };
  return {
    name,
    label,
    field: {
      type: 'remoteSelect',
      props: {
        placeholder: '输入合同ID或者合同名搜索',
        fetchOptions: searchContract,
        formatFetchOptionsParams: (inputValue: string, ctx: any) => {
          const cpCompanyId = ctx.form?.getFieldValue(copyrightCompanyName);
          return [cpCompanyId, inputValue];
        },
        formatOptions: (res: any) => {
          const { code, data } = res;
          if (code === '0') {
            return listToOptions(data.list, 'copyrightId', 'contract');
          }
          return [];
        },
        ...restFieldProps,
      },
    },
    initialDisabled: isBoolean(dependency) ? dependency : false,
    remoteSource:
      mode !== 'create' &&
      getContractSearchConfig({
        params: {
          filters: {
            cpCompanyId: '#{record.cpCompanyId}',
            keyWord: `#{record.${name}}`,
          },
        },
        convertParams: true,
        converter: true,
      }),
    dependency: dependencyConfig(),
  };
};

// 表格列tooltips配置，最大1000px，小于1000px自动收缩
export const getTableColumnToolTipsConfig = ({ key, title, width = 300 }: any) => {
  return {
    key,
    title,
    ellipsis: {
      showTitle: false,
    },
    width,
    render: ({ record }: RenderCtx) => {
      const text = record[key];
      return (
        <Tooltip
          placement="topLeft"
          overlayInnerStyle={{
            width: 'fit-content',
            maxWidth: '1000px',
          }}
          title={text}
        >
          {text}
        </Tooltip>
      );
    },
  };
};

// 禁用此刻时间之前所有选项的datepicker配置
export const getLimitAfterNowDatePickerConfig = ({ name, label, ...restProps }: any) => {
  return {
    name,
    label,
    field: {
      type: 'datepicker',
      props: {
        valueFormat: 'YYYY-MM-DD HH:mm:ss',
        format: 'YYYY-MM-DD HH:mm:ss',
        showTime: { defaultValue: moment('00:00:00', 'HH:mm:ss') },
        disabledTime: (date: Moment) => {
          const currentTime = moment();
          const hours = currentTime.get('hours');
          const minutes = currentTime.get('minutes');
          const seconds = currentTime.get('seconds');
          const isSameDate = moment().isSame(date, 'date');
          const isSameHour = moment().isSame(date, 'hour');
          // const isSameMinute = moment().isSame(date, 'minute');
          // 仅精确到小时
          if (isSameDate) {
            if (!isSameHour) {
              return {
                disabledHours: () => numberRange(0, hours),
                disabledMinutes: () => numberRange(0, 0),
                disabledSeconds: () => numberRange(0, 0),
              };
            }
            return {
              disabledHours: () => numberRange(0, hours),
              disabledMinutes: () => numberRange(0, minutes),
              disabledSeconds: () => numberRange(0, seconds),
            };
          }
          return {
            disabledHours: () => numberRange(0, 0),
            disabledMinutes: () => numberRange(0, 0),
            disabledSeconds: () => numberRange(0, 0),
          };
        },
        disabledDate: (current: Moment) => {
          return current && current < moment().add(-1, 'days').endOf('day');
        },
        style: {
          width: '100%',
        },
      },
    },
    ...restProps,
  };
};

export type TableColumnTagConfigParam = {
  key: string;
  title: string;
  constantMap: Map<string, any> | Record<string, any>;
  color?: string;
  toolTipsKey?: string;
};

export const getTableColumnTagConfig = ({
  key,
  title,
  constantMap,
  color = 'processing',
  toolTipsKey,
}: TableColumnTagConfigParam) => {
  return {
    key,
    title,
    render: ({ record }: RenderCtx) => {
      const target = record[key];
      let text;
      let iconNode = <></>;
      if (constantMap instanceof Map) {
        text = constantMap.get(target);
      } else {
        text = constantMap[target];
      }
      if (toolTipsKey && record[toolTipsKey]) {
        iconNode = (
          <Tooltip title={record[toolTipsKey]}>
            <ExclamationCircleOutlined />
          </Tooltip>
        );
      }
      return (
        <>
          <Tag icon={iconNode} color={color}>
            {text}
          </Tag>
        </>
      );
    },
  };
};

export type UploadConfigParam = {
  name: string;
  label: string;
  upLoadType: string;
  uploadExtendParams?: KeyObj;
  uploadChildren?: React.ReactNode;
  uploadButtonText?: string;
  [key: string]: any;
};

export const getUploadConfig = ({
  name,
  label,
  upLoadType,
  uploadExtendParams,
  uploadChildren,
  uploadButtonText = '选择文件',
  fieldRestProps,
  ...restProps
}: UploadConfigParam) => {
  return {
    name,
    label,
    valuePropName: 'fileList',
    getValueFromEvent(event: any) {
      if (!event || !Array.isArray(event)) {
        return event;
      }
      const fileList = event.reduce((uploadedList, fileItem) => {
        // eslint-disable-next-line @typescript-eslint/no-shadow
        const { name, status, response } = fileItem;
        if (status === 'done' && response && response.response) {
          uploadedList.push({
            name,
            status,
            url: response.response.sourceFile,
            ...response.response,
          });
        } else {
          uploadedList.push(fileItem);
        }
        return uploadedList;
      }, []);
      return fileList;
    },
    field: {
      type: 'upload',
      props: {
        request: {
          url: `/cos/uploadFile?type=${upLoadType}`,
          params: uploadExtendParams,
        },
        maxCount: 1,
        children: uploadChildren || <Button type="primary">{uploadButtonText}</Button>,
        ...fieldRestProps,
      },
    },
    ...restProps,
  };
};
